﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.Web.Routing;
using nanoCMS.Core.Extensions;

namespace nanoCMS.Core.WebProviders.HtmlHelpers {
	public static class LinkHelper {
		public static MvcHtmlString Link(this HtmlHelper htmlHelper, string text, string link, object routeValues = null, object htmlAttributes = null) {
			

			return Link(htmlHelper, text, link, new RouteValueDictionary(routeValues.IfNullSet(new object())),
							HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes.IfNullSet(new object())));
		}

		public static MvcHtmlString Link(this HtmlHelper htmlHelper, string text, string link, RouteValueDictionary routeValues, IDictionary<string, object> htmlAttributes) {
			return
				 MvcHtmlString.Create(CustomGenerateLink(htmlHelper.ViewContext.RequestContext,
																	  htmlHelper.RouteCollection, text, link, routeValues, htmlAttributes));
		}


		public static string CustomGenerateLink(RequestContext requestContext, RouteCollection routeCollection, string text, string link, RouteValueDictionary routeValues, IDictionary<string, object> htmlAttributes) {
			string url = CustomUrl(requestContext, link, routeValues);
			TagBuilder linkTag = new TagBuilder("a");
			linkTag.MergeAttribute("href", url);
			if (htmlAttributes != null)
				linkTag.MergeAttributes(htmlAttributes);
			linkTag.InnerHtml = text;
			return linkTag.ToString();
		}



		public static string CustomUrl(RequestContext requestContext, string link, RouteValueDictionary routeValues) {
			var request = requestContext.HttpContext.Request.Url;

			if (request == null) throw new Exception("Request is null!!!");
			StringBuilder url = new StringBuilder();
			url.Append(request.Scheme);
			url.Append(Uri.SchemeDelimiter);
			url.Append(request.Host);

			if (!String.IsNullOrEmpty(requestContext.HttpContext.Request.ApplicationPath))
				url.Append(requestContext.HttpContext.Request.ApplicationPath);
			url.Append("/" + link);

			if (routeValues != null && routeValues.Any()) {
				url.Append("?");
				foreach (var routeValue in routeValues) {
					url.Append(routeValue.Key + "=" + routeValue.Value);
					url.Append("&");
				}
			}
			return url.ToString().TrimEnd('&');
		}

		public static MvcHtmlString UrlInnerHome()
		{
			string link = String.Empty;
			return MvcHtmlString.Create(CustomUrl(System.Web.HttpContext.Current.Request.RequestContext, link, new RouteValueDictionary()));
		}


		public static MvcHtmlString UrlInner(object routeValues)
		{
			var currentRequestContext = System.Web.HttpContext.Current.Request.RequestContext;
			string link = String.Empty;
			RouteValueDictionary routeValueDictionary = new RouteValueDictionary(routeValues);
			if (routeValueDictionary.ContainsKey("link"))
			{
				link = routeValueDictionary["link"].ToString();
				routeValueDictionary.Remove("link");
			} else if (currentRequestContext.RouteData.Values["link"] != null)
				link = currentRequestContext.RouteData.Values["link"].ToString();

			return
				MvcHtmlString.Create(CustomUrl(currentRequestContext, link, routeValueDictionary));
		}

		public static MvcHtmlString UrlInner(this HtmlHelper htmlHelper, object routeValues)
		{
			string link = String.Empty;
			if (htmlHelper.ViewContext.RequestContext.RouteData.Values["link"] != null)
				link = htmlHelper.ViewContext.RequestContext.RouteData.Values["link"].ToString();

			return
				MvcHtmlString.Create(CustomUrl(htmlHelper.ViewContext.RequestContext, link, new RouteValueDictionary(routeValues)));
		}

		/// <summary>
		/// Home url
		/// </summary>
		/// <param name="htmlHelper"></param>
		/// <returns></returns>
		public static MvcHtmlString UrlInnerHome(this HtmlHelper htmlHelper)
		{
			string link = String.Empty;
			return MvcHtmlString.Create(CustomUrl(htmlHelper.ViewContext.RequestContext, link, new RouteValueDictionary()));
		}

		public static MvcHtmlString LinkInner(this HtmlHelper htmlHelper, string text, object routeValues, object htmlAttributes) {
			return LinkInner(htmlHelper, text, new RouteValueDictionary(routeValues), HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
		}


		public static MvcHtmlString Url(RequestContext requestContext, string link, object routeValues = null)
		{
			if (routeValues == null) routeValues = new object();
			return MvcHtmlString.Create(
				CustomUrl(requestContext, link, new RouteValueDictionary(routeValues))
				);
		}


		public static MvcHtmlString Url(this HtmlHelper htmlHelper, string link, object routeValues = null)
		{
			if (routeValues == null) routeValues = new object();
			return MvcHtmlString.Create(
				CustomUrl(htmlHelper.ViewContext.RequestContext, link, new RouteValueDictionary(routeValues))
				);
		}


		/// <summary>
		/// Doest't change link only parameters
		/// </summary>
		/// <param name="htmlHelper"></param>
		/// <param name="text"></param>
		/// <param name="routeValues"></param>
		/// <param name="htmlAttributes"></param>
		/// <returns></returns>
		public static MvcHtmlString LinkInner(this HtmlHelper htmlHelper, string text, RouteValueDictionary routeValues, IDictionary<string, object> htmlAttributes) {
			string link = String.Empty;
			if (htmlHelper.ViewContext.RequestContext.RouteData.Values["link"] != null)
				link = htmlHelper.ViewContext.RequestContext.RouteData.Values["link"].ToString();

			return MvcHtmlString.Create(
				CustomGenerateLink(htmlHelper.ViewContext.RequestContext,
										htmlHelper.RouteCollection, text, link, routeValues, htmlAttributes));
		}

	}
}
